//
// Created by wxd on 2025/9/12.
// 基于互斥锁的简易的封装一个线程安全的vector
//

#pragma once

#ifndef SAFE_VECTOR_H
#define SAFE_VECTOR_H

#include <vector>
#include <mutex>
#include <shared_mutex>
#include <optional>

template<typename T>
class SafeVector {
public:
    SafeVector() = default;

    explicit SafeVector(size_t size) {
        mData.reserve(size);
    }

    ~SafeVector() = default;

    SafeVector(const SafeVector &) = delete;
    SafeVector& operator=(const SafeVector &) = delete;


    // 写入操作 - 需要独占锁  复制构造，需要内存分配和内容复制
    void push_back(const T& value) {
        std::unique_lock lock(mLock);
        mData.push_back(value);
    }

    // 移动拷贝，不需要重新分配内存和内容复制，只需要交换指针
    void push_back(T&& value) {
        std::unique_lock lock(mLock);
        mData.push_back(std::move(value));
    }

    template<typename... Args>
    void emplace_back(Args&&... args) {
        std::unique_lock lock(mLock);
        mData.emplace_back(std::forward<Args>(args)...);
    }

    void pop_back() {
        std::unique_lock lock(mLock);
        if (!mData.empty()) {
            mData.pop_back();
        }
    }

    void clear() {
        std::unique_lock lock(mLock);
        mData.clear();
    }

    // 读取操作 - 使用共享锁（允许多个线程同时读取）
    size_t size() const {
        std::shared_lock lock(mLock);
        return mData.size();
    }

    bool empty() const {
        std::shared_lock lock(mLock);
        return mData.empty();
    }

    // 安全的元素访问（返回副本而不是引用）
    std::optional<T> at(size_t index) const {
        std::shared_lock lock(mLock);
        if (index < mData.size()) {
            return mData[index];
        }
        return std::nullopt;
    }

    // 批量读取（更高效）
    std::vector<T> get_copy() const {
        std::shared_lock lock(mLock);
        return mData;
    }

    // 遍历操作（使用函数回调）
    template<typename Func>
    void for_each(Func func) const {
        std::shared_lock lock(mLock);
        for (const auto& item : mData) {
            func(item);
        }
    }

    // 安全的交换操作
    void swap(std::vector<T>& other) {
        std::unique_lock lock(mLock);
        mData.swap(other);
    }

private:
    mutable std::shared_mutex mLock;       // 读写锁保证并发安全
    std::vector<T> mData;
};

#endif //SAFE_VECTOR_H
